/**
  ******************************************************************************
  * @file
  * @brief
  * @author luffy
  * @version V1.0.0
  * @date 2022/12/13
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "dev_switch.h"
#include "FreeRTOS.h"
#include "task.h"
#include "main_task.h"
#include "led_task.h"
#include "expand_io.h"
#include "A_shell.h"
#include "w5500_fun.h"

/* Private defines -----------------------------------------------------------*/
#define LED_S1_MASK         (0xFFF8)   //样品管LED_S1提取GPIO位
#define LED_S2_MASK         (0xFFC7)	 //样品管LED_S2提取GPIO位
#define LED_S3_MASK         (0xFE3F)   //样品管LED_S3提取GPIO位
#define LED_ALL_OFF_MASK    (0x01FF)	 //扩展LED灯全关掩码

#define EXTRACT_BITS(value, pos, len)  (((value) >> (pos)) & ((1 << (len)) - 1))  //提取某值从多少位开始的某长度后的值

/* Private Struct  -----------------------------------------------------------*/


/* Private enum    -----------------------------------------------------------*/


/* Private Variable  ---------------------------------------------------------*/
//Pointer

//Array

//Const

/* Private Func  ---------------------------------------------------------*/
static void LedTask(void);

/* Func Define   ---------------------------------------------------------*/
/***********************************************************************************
 * @brief 呼吸灯进程
 * ex:
 * @par   输入参数：无
 *        输出参数：无
 * @retval返回值：无
 **********************************************************************************/
void LedTaskProcess(void *pvParameters)
{
		SWITCH_ON_OFF(LED_RUN, SWITCH_OFF);
    for (;;)
    {
        LedTask();
        vTaskDelay(pdMS_TO_TICKS(500));
    }
}

/******************************************************************/
/*功能说明：点亮对应样品管的扩展LED灯
* 输入参数：led_color_e LedColor - LED灯的颜色
*           led_tube_pos_e LedPos - 对应的样品管索引值值
* 输出参数：无
* 返回值：	无
*/
/******************************************************************/
void ExpandLed_Light(led_color_e LedColor,led_tube_pos_e LedPos)
{
    int led_pin[] = {LED_B1, LED_R1, LED_G1, LED_Y1, LED_B2,LED_R2,
                     LED_G2, LED_Y2, LED_B3, LED_R3, LED_G3,LED_Y3};
    
    uint16_t Led_Index = 0;
    uint16_t save_led_index = 0;                 
    Led_Index = led_pin[LedColor + LedPos * 4];
    
    //更换LED灯颜色时，只改变灯号对应的GPIO口，未改变的灯号不改变                 
    save_led_index = Expand_IO_GetState(TCA9535_1);                  
    save_led_index ^= LED_ALL_OFF_MASK;
                     
    if(S1 == LedPos)
    {
        save_led_index &= LED_S1_MASK;
        Led_Index |= save_led_index;   
    }
    else if(S2 == LedPos)
    {
        save_led_index &= LED_S2_MASK;
        Led_Index |= save_led_index;  
    }
    else if(S3 == LedPos)  
    {
        save_led_index &= LED_S3_MASK;
        Led_Index |= save_led_index;  
    }

    Expand_IO_SetState(TCA9535_1,EXPAND_IO_CLOSE,Led_Index);   
}

/******************************************************************/
/*功能说明：获取指定扩展LED的GPIO状态(对应灯号以及灯的颜色)
* 输入参数：led_color_e LedColor - LED灯的颜色
*           led_tube_pos_e LedPos - 对应的样品管索引值值
* 输出参数：无
* 返回值：	无
*/
/******************************************************************/
void ExpandLed_Prestate_Get(DataServer_t* inst,uint8_t ledPos)
{
    uint16_t save_led_index = 0;

    save_led_index = Expand_IO_GetState(TCA9535_1);                  
		save_led_index = EXTRACT_BITS(save_led_index,ledPos * 3,3);
		inst->led_saved_color |= save_led_index;   
}

/******************************************************************/
/*功能说明：将保存的指定灯的状态恢复
* 输入参数：led_color_e LedColor - LED灯的颜色
*           led_tube_pos_e LedPos - 对应的样品管索引值值
* 输出参数：无
* 返回值：	无
*/
/******************************************************************/
void ExpandLed_Restore(DataServer_t* inst,uint8_t ledPos)
{
  uint16_t read_led_color = 0;
	uint16_t led_color = 0;
	
	read_led_color = Expand_IO_GetState(TCA9535_1);    
	
	if(S1 == ledPos)
	{
			read_led_color &= LED_S1_MASK;
	}
	else if(S2 == ledPos)
	{
			read_led_color &= LED_S2_MASK;
	}
	else if(S3 == ledPos)  
	{
			read_led_color &= LED_S3_MASK;
	}

	led_color = read_led_color | inst->led_saved_color;
	Expand_IO_SetState(TCA9535_1,EXPAND_IO_CLOSE,led_color);   
}

/*****************************************************************
* 功能说明：扩展LED显示初始化
* 输入参数：无
* 输出参数：无
* 返回值：无
******************************************************************/
void ExpandLed_Init(void)
{
    Expand_IO_SetState(TCA9535_1,EXPAND_IO_OPEN,LED_ALL_OFF_MASK);
    Expand_IO_SetState(TCA9535_1,EXPAND_IO_CLOSE,LED_G1|LED_G2|LED_G3);    
}

/****************************************************/
/* 功能说明：返回设置的样品管位号
/* 输入参数：int index - 待查找的样品管索引值
 *           uint8_t posMsk - 样品管索引值
*  输出参数：
*  返回值：若index标识的样品管在posMask标识的索引值内，返回样品管索引值；若index标识的样品管不在posMask标识的索引值内，则返回-1
*/
/****************************************************/
int get_sample_pos(int index, uint8_t posMsk) 
{
    if (posMsk & (1 << index)) 
    {
        return index; 
    }
    return -1; 
}

extern uint8_t disconnect_flag;
/***********************************************************/
/*功能说明：控制LED任务进程
* 输入参数：TestState_e test_state - 测试状态enum类型值
*           uint8_t data_server.press_par.pos - 样品管索引值
* 输出参数：无
* 返回值：无
*/
/***********************************************************/
static void LedTask(void)
{
    static bool flag = true;

	
    if (flag == false) 
    {
        SWITCH_ON_OFF(LED_RUN, SWITCH_ON);
        flag = true;
    }
    else
    {
        SWITCH_ON_OFF(LED_RUN, SWITCH_OFF);
        flag = false;
    }
    
    #if defined SUPPORT_LED_EXPAND
    //实验正常进行中，实验的样品管通道亮黄灯
    if(RUNING == test_state && true != data_server.isDisconnected && data_server.led_control_flag != true)
    {
        int sample_pos = 0;
        //选中的样品管亮黄灯,未选中的样品管亮绿灯
        for(int i = 0;i < 3;i++)
        {
            sample_pos = get_sample_pos(i,data_server.press_par.start_pos);
            if( -1 != sample_pos)
            {             
                ExpandLed_Light(YELLOW,sample_pos);
            }
            else
            {         
                ExpandLed_Light(GREEN,i);
            }
            
        }
    }
    //断连亮红灯
    else if (true == data_server.isDisconnected && data_server.led_control_flag != true)
    {
          Expand_IO_SetState(TCA9535_1,EXPAND_IO_OPEN,LED_ALL_OFF_MASK);
          Expand_IO_SetState(TCA9535_1,EXPAND_IO_CLOSE,LED_R1|LED_R2|LED_R3);  
    }
    //其他情况下，亮绿灯
    else if (data_server.led_control_flag != true)
    {
          Expand_IO_SetState(TCA9535_1,EXPAND_IO_OPEN,0XFFFF);
          Expand_IO_SetState(TCA9535_1,EXPAND_IO_CLOSE,LED_G1|LED_G2|LED_G3);      
    }
    #endif    
}

/******************* (C) COPYRIGHT 2022 CIQTEK luffy *****END OF FILE****/
